﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Data.Linq.Mapping;
using System.Data.Linq;

namespace Organizer.Model
{
    [Table]
    public class Task : Base<Task>
    {
        [Column(IsPrimaryKey = true, DbType = "UniqueIdentifier NOT NULL", CanBeNull = false, AutoSync = AutoSync.OnInsert)]
        public Guid Id { get; private set; }

        private readonly EntitySet<CategoryTask> _categoryTasks = new EntitySet<CategoryTask>();
        /// <summary>
        /// Коллекция зависимых CategoryTask
        /// </summary>
        [Association(Storage = "_categoryTasks", OtherKey = "_taskId", ThisKey = "Id", DeleteRule = "CASCADE")]
        public EntitySet<CategoryTask> CategoryTasks
        {
            get { return _categoryTasks; }
            set { _categoryTasks.Assign(value); }
        }
        
        [Column]
        private string _name; //тема задачи, ее описание. 
        public string Name
        {
            get { return _name; }
            set 
            {               
                NotifyPropertyChanging(() => this.Name);
                _name = value;
                NotifyPropertyChanged(() => this.Name);
            }
        }
        
        [Column]
        private bool _done = false; 
        /// <summary>
        /// Выполнена ли задача
        /// </summary>
        public bool Done
        {
            get { return _done; }
            set 
            {
                if (_done == value) return;
                NotifyPropertyChanging(() => this.Done);
                _done = value;
                NotifyPropertyChanged(() => this.Done);
            }
        }

        private string _description;
        [Column(CanBeNull = true)]
        public string Description
        {
            get { return _description; }
            set
            {
                if (_description == value) return;
                NotifyPropertyChanging(() => this.Description);
                _description = value;
                NotifyPropertyChanged(() => this.Description);
            }
        }

        private DateTime _timeStart; //время начала дела/задачи
        [Column(DbType = "datetime")]
        public DateTime TimeStart
        {
            get { return _timeStart; }
            set
            {
                if (_timeStart == value) return;
                NotifyPropertyChanging(() => this.TimeStart);
                _timeStart = value;
                NotifyPropertyChanged(() => this.TimeStart);
            }
        }      

        private DateTime _timeCreate; //время создания задачи (автоматом)
        [Column(DbType = "datetime")]
        public DateTime TimeCreate
        {
            get { return _timeCreate; }
            set
            {
                if (_timeCreate == value) return;
                NotifyPropertyChanging(() => this.TimeCreate);
                _timeCreate = value;
                NotifyPropertyChanged(() => this.TimeCreate);
            }
        }

        private DateTime _timeEnd; //время конца дела/задачи. а-ля длительность. но зачем? 
        [Column(DbType = "datetime")]
        public DateTime TimeEnd
        {
            get { return _timeEnd; }
            set
            {
                if (_timeEnd == value) return;
                NotifyPropertyChanging(() => this.TimeEnd);
                _timeEnd = value;
                NotifyPropertyChanged(() => this.TimeEnd);
            }
        }

        private DateTime _timeRemind; //время напоминалки 
        [Column(DbType = "datetime")]
        public DateTime TimeRemind
        {
            get { return _timeRemind; }
            set
            {
                if (_timeRemind == value) return;
                NotifyPropertyChanging(() => this.TimeRemind);
                _timeRemind = value;
                NotifyPropertyChanged(() => this.TimeRemind);
            }
        }


        private DateTime _timeRemindInterval;
        public DateTime TimeRemindInterval
        {
            get { return _timeRemindInterval; }
            set
            {
                _timeRemindInterval = value;
                TimeRemind.Add(_timeRemindInterval.TimeOfDay);
            }
        }

        [Column(CanBeNull = true)]
        private Guid _linkedManId;
        /// <summary>
        /// id человека с которым связана задача (позвонить Васе)
        /// </summary>         
        public Man LinkedMan
        {
            get
            {
                return OrganizerDataContext.Instance.GetManById(_linkedManId);
            }
            set 
            {
                NotifyPropertyChanging(() => this.LinkedMan);
                if (value != null)
                    _linkedManId = value.Id;
                else
                    _linkedManId = Guid.Empty;
                NotifyPropertyChanged(() => this.LinkedMan);            
            }
        }

        [Column(CanBeNull = true)]
        private Guid _responsibleManId;
        /// <summary>
        /// id человека отвественного за задачу (по умолчанию - Я)                       
        /// </summary>
        public Man ResponsibleMan
        {
            get
            {
                return OrganizerDataContext.Instance.GetManById(_responsibleManId);
            }
            set 
            {
                NotifyPropertyChanging(() => this.ResponsibleMan);
                if (value != null)
                    _responsibleManId = value.Id;
                else
                    _responsibleManId = Guid.Empty;
                NotifyPropertyChanged(() => this.ResponsibleMan);
            }          
        }

        private Guid _categoryTaskId; //связь 

        //id объекта-напоминания
        [Column(CanBeNull = true)]
        private Guid _reminderId;
        public Guid ReminderId
        {
            get { return _reminderId; }            
        }

        [Column]
        private bool _remindEnable;
        public bool RemindEnable
        {
            get { return _remindEnable; }
            set
            {
                if (_remindEnable == value) return;
                NotifyPropertyChanging(() => this.RemindEnable);
                _remindEnable = value;
                NotifyPropertyChanged(() => this.RemindEnable);
            }
        }



        /// <summary>
        /// Переопределение ToString() для удобного отображения 
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            return Name;
        }
        
        //копировать свойста объекта
        public void Assign(Task dest)
        {
            dest.Id = Id;
            dest.Name = _name;
            dest.Description = _description;
            dest.TimeCreate = _timeCreate;
            dest.TimeStart = _timeStart;
            dest.TimeRemindInterval = _timeRemindInterval;
            dest.TimeEnd = _timeEnd;
            dest._linkedManId = _linkedManId;
            dest._responsibleManId = _responsibleManId;
            dest._categoryTaskId = _categoryTaskId;
            dest.RemindEnable = _remindEnable;
            dest.TimeRemind = _timeRemind;

        }

        #region construtors

        public Task()
        {
            Id = Guid.NewGuid();
            _timeCreate = DateTime.Now;
            _timeStart = DateTime.Now;
            _timeEnd = DateTime.Now;
            _timeRemind = DateTime.Now; 
            _reminderId = Guid.NewGuid();
        }

        public Task(string pName)
            : this()
        {
            Name = pName;
            _reminderId = Guid.NewGuid();
            _timeCreate = DateTime.Now;
            _timeStart = DateTime.Now;
            _timeEnd = DateTime.Now;
            _timeRemind = DateTime.Now; 
        }

        public Task(string pName, string pDescription)
            : this()
        {
            Name = pName;
            Description = pDescription;
            _reminderId = Guid.NewGuid();
            _timeCreate = DateTime.Now;
            _timeStart = DateTime.Now;
            _timeEnd = DateTime.Now;
            _timeRemind = DateTime.Now; 
        }

        #endregion
    }
}
